#include <sys/epoll.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>

#define MAX_EVENTS 1024
#define BUFFER_SIZE 4096

// 回调函数类型定义
typedef void (*callback_t)(int fd, void* arg);

// 文件描述符信息结构
typedef struct {
    int fd;             // 文件描述符
    callback_t cb_read; // 读回调函数
    void* arg;         // 回调参数：保存当前文件描述符被哪个反应堆监听
} fd_context_t;

// 反应堆主结构
typedef struct {
    int epfd;                   // epoll文件描述符
    fd_context_t* contexts[MAX_EVENTS]; // 保存文件描述符上下文
} reactor_t;

// 创建反应堆
reactor_t* reactor_create() {
    reactor_t* reactor = malloc(sizeof(reactor_t));
    if (!reactor) {
        perror("malloc reactor");
        return NULL;
    }

    // 创建epoll实例
    reactor->epfd = epoll_create1(0);
    if (reactor->epfd < 0) {
        perror("epoll_create1");
        free(reactor);
        return NULL;
    }

    // 初始化上下文数组
    memset(reactor->contexts, 0, sizeof(reactor->contexts));
    return reactor;
}

// 添加文件描述符到反应堆
int reactor_add_fd(reactor_t* reactor, int fd, callback_t cb, void* arg) {
    // 创建文件描述符上下文
    fd_context_t* context = malloc(sizeof(fd_context_t));
    if (!context) {
        perror("malloc context");
        return -1;
    }

    // // 设置非阻塞模式
    // int flags = fcntl(fd, F_GETFL, 0);
    // if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0) {
    //     perror("fcntl");
    //     free(context);
    //     return -1;
    // }

    // 初始化上下文
    context->fd = fd;
    context->cb_read = cb;
    context->arg = arg;

    // 添加到epoll监听
    struct epoll_event ev;
    ev.events = EPOLLIN;
    ev.data.ptr = context;

    if (epoll_ctl(reactor->epfd, EPOLL_CTL_ADD, fd, &ev) < 0) {
        perror("epoll_ctl add");
        free(context);
        return -1;
    }

    // 保存到上下文数组
    reactor->contexts[fd] = context;
    return 0;
}

// 从反应堆移除文件描述符
int reactor_remove_fd(reactor_t* reactor, int fd) {
    if (fd >= MAX_EVENTS || !reactor->contexts[fd]) {
        fprintf(stderr, "Invalid fd or not registered\n");
        return -1;
    }

    // 从epoll移除
    if (epoll_ctl(reactor->epfd, EPOLL_CTL_DEL, fd, NULL) < 0) {
        perror("epoll_ctl del");
        return -1;
    }

    // 释放上下文内存
    free(reactor->contexts[fd]);
    reactor->contexts[fd] = NULL;
    close(fd);
    return 0;
}

// 运行反应堆事件循环
void reactor_run(reactor_t* reactor) {
    struct epoll_event events[MAX_EVENTS];
    
    while (1) {
        // 等待事件
        int n = epoll_wait(reactor->epfd, events, MAX_EVENTS, -1);
        if (n < 0) {
            perror("epoll_wait");
            break;
        }

        // 处理所有就绪事件
        for (int i = 0; i < n; i++) {
            fd_context_t* context = events[i].data.ptr;
            if (context->cb_read) {
                context->cb_read(context->fd, context->arg);
            }
        }
    }
}

// 销毁反应堆
void reactor_destroy(reactor_t* reactor) {
    if (!reactor) return;
    
    // 释放所有文件描述符上下文
    for (int i = 0; i < MAX_EVENTS; i++) {
        if (reactor->contexts[i]) {
            close(i);
            free(reactor->contexts[i]);
        }
    }
    
    close(reactor->epfd);
    free(reactor);
}

// 示例读取回调函数
void handle_read(int fd, void* arg) {
    char buffer[BUFFER_SIZE];
    ssize_t n;
    
    // 边缘触发模式下需要读取所有可用数据
    while ((n = read(fd, buffer, BUFFER_SIZE)) > 0) {
        buffer[n] = '\0';
        printf("Received %zd bytes from fd %d: %s\n", n, fd, buffer);
    }
    
    // 读取完毕或连接关闭
    if (n == 0) {
        printf("Connection closed on fd %d\n", fd);
        reactor_remove_fd(arg, fd);
    } else if (n < 0 && errno != EAGAIN && errno != EWOULDBLOCK) {
        perror("read error");
        reactor_remove_fd(arg, fd);
    }
}

void read_fd(int fd, void *arg)
{
    char buffer[1024];
    read(fd, buffer, sizeof(buffer));
    for(int i = 0; i < 3; i++)
    {
        printf("fd1 = %s\n", buffer);
    }
}

void read_fd2(int fd, void *arg)
{
    char buffer[1024];
    read(fd, buffer, sizeof(buffer));
    for(int i = 0; i < 4; i++)
    {
        printf("fd2 = %s\n", buffer);
    }
}

void read_fd3(int fd, void *arg)
{
    char buffer[1024];
    read(fd, buffer, sizeof(buffer));
    for(int i = 0; i < 5; i++)
    {
        printf("fd3 = %s\n", buffer);
    }
}

void read_fd4(int fd, void *arg)
{
    char buffer[1024];
    read(fd, buffer, sizeof(buffer));
    for(int i = 0; i < 6; i++)
    {
        printf("fd4 = %s\n", buffer);
    }
}

int main(int argc, char **argv) {
   
    if (argc != 5)
    {
        printf("Please input filename!\n");
        exit(1);
    }
    
    int fd = open(argv[1], O_CREAT | O_RDWR, 0655);
    if (fd == -1)
    {
        printf("%d:file open error:%s\n", __LINE__, strerror(errno));
    }

    int fd2 = open(argv[2], O_CREAT | O_RDWR, 0655);
    if (fd2 == -1)
    {
        printf("%d:file open error:%s\n", __LINE__, strerror(errno));
    }

    int fd3 = open(argv[3], O_CREAT | O_RDWR, 0655);
    if (fd2 == -1)
    {
        printf("%d:file open error:%s\n", __LINE__, strerror(errno));
    }

    int fd4 = open(argv[4], O_CREAT | O_RDWR, 0655);
    if (fd2 == -1)
    {
        printf("%d:file open error:%s\n", __LINE__, strerror(errno));
    }

    reactor_t* reactor = reactor_create();
    if (!reactor) {
        return EXIT_FAILURE;
    }

    // 示例：添加标准输入监听
    reactor_add_fd(reactor, STDIN_FILENO, handle_read, reactor);
    reactor_add_fd(reactor, fd, read_fd, reactor);
    reactor_add_fd(reactor, fd2, read_fd2, reactor);
    reactor_add_fd(reactor, fd3, read_fd3, reactor);
    reactor_add_fd(reactor, fd4, read_fd4, reactor);

    
    printf("Reactor started. Type something...\n");
    
    // 运行事件循环
    reactor_run(reactor);
    
    // 清理资源
    reactor_destroy(reactor);
    return EXIT_SUCCESS;
}